﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using Cubicle.Core.DataContracts;
using Cubicle.Core.Interfaces;

namespace Cubicle.Core.Shared
{
    public class AggregateResolver : IResolver
    {

        // Alternative assembly resolvers
        private readonly List<IResolver> _resolvers = new List<IResolver>();

        public AggregateResolver(IEnumerable<IResolver> resolvers)
        {
            _resolvers.AddRange(resolvers);
        }

        public bool AddResolver(IResolver resolver)
        {
            _resolvers.Add(resolver);
            return true;
        }

        #region Implementation of IResolver

        public bool AutoAssemblyResolveState { get; set; }

        public Assembly ResolveAssembly(string path)
        {
            return _resolvers
                .Select(x => x.ResolveAssembly(path))
                .FirstOrDefault();
        }

        public bool CanResolve(string asmId)
        {
            return _resolvers
                .Select(x => x.CanResolve(asmId))
                .FirstOrDefault();
        }

        public IEnumerable<AssemblyData> ListAssemblies()
        {
            return _resolvers
                .SelectMany(x => x.ListAssemblies()).ToList();
        }

        public IEnumerable<TypeData> ListTypes(string asmId)
        {
            return _resolvers
                .SelectMany(x => x.ListTypes(asmId)).ToList();
        }

        public IEnumerable<TypeData> FindAll<TInterface>()
        {
            return _resolvers
                .SelectMany(x => x.FindAll<TInterface>()).ToList();
        }

        public IEnumerable<TypeData> FindAll(string interfaceName)
        {
            return _resolvers
                .SelectMany(x => x.FindAll(interfaceName)).ToList();
        }

        public IEnumerable<Type> FindTypes<TInterface>(IEnumerable<string> typeNames)
        {
            return _resolvers
                .SelectMany(x => x.FindTypes<TInterface>(typeNames)).ToList();
        }

        public IEnumerable<Type> FindTypes<TInterface>()
        {
            return _resolvers
                .SelectMany(x => x.FindTypes<TInterface>()).ToList();
        }

        #endregion
    }
}